﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Camera
{
    public Vector3 origin;
    public Vector3 lower_left_corner;
    public Vector3 horizontal;
    public Vector3 vertical;
    public Vector3 u, v, w;
    float lens_radius = 0;
    public Camera(float vfov, float aspect)
    {
        float unitAngle = Mathf.PI / 180f * vfov;
        float halfHeight = Mathf.Tan(unitAngle * 0.5f);
        float halfWidth = aspect * halfHeight;
        lower_left_corner = new Vector3(-halfWidth, -halfHeight, -1f);
        horizontal = new Vector3(2 * halfWidth, 0, 0);
        vertical = new Vector3(0, 2 * halfHeight, 0);
        origin = Vector3.zero;
    }
    public Camera(Vector3 lookFrom, Vector3 lookat, Vector3 vup, float vfov, float aspect)
    {
        float unitAngle = Mathf.PI / 180f * vfov;
        float halfHeight = Mathf.Tan(unitAngle * 0.5f);
        float halfWidth = aspect * halfHeight;
        origin = lookFrom;
        w = (lookat - lookFrom).normalized;
        u = Vector3.Cross(vup, w).normalized;
        v = Vector3.Cross(w, u).normalized;
        lower_left_corner = lookFrom + w  - halfWidth  * u - halfHeight  * v;
        horizontal = 2 * halfWidth * u ;
        vertical = 2 * halfHeight * v ;
    }
    public Camera(Vector3 lookFrom,Vector3 lookat,Vector3 vup, float vfov, float aspect,float aperture,float focus_dist)
    {
        lens_radius = aperture / 2;


        float unitAngle = Mathf.PI / 180f * vfov;
        float halfHeight = Mathf.Tan(unitAngle * 0.5f);
        float halfWidth = aspect * halfHeight;
        origin = lookFrom;
         w = (lookat - lookFrom).normalized;
         u = Vector3.Cross(vup, w).normalized;
         v = Vector3.Cross(w, u).normalized;
        lower_left_corner = lookFrom + w*focus_dist - halfWidth*focus_dist * u - halfHeight *focus_dist* v;
        horizontal = 2 * halfWidth * u * focus_dist;
        vertical = 2 * halfHeight * v * focus_dist;
    }
    public Ray GetRay(float u, float v)
    {
        if (lens_radius == 0)
        {
            return new Ray(origin, lower_left_corner + u * horizontal + v * vertical - origin);
        }
        else
        {
            Vector3 rd = lens_radius * _M.GetRandomPointInUnitDisk();
            Vector3 offset = rd.x * this.u + rd.y * this.v;
            return new Ray(origin + offset, lower_left_corner + u * horizontal + v * vertical - origin - offset);
        }
    }
}
